import io
import sys
from python_baway.common.xcommon import sep
from python_baway.exercise.io.x_files import linux_words_txt
from python_baway.exercise.io.x_files import red_mansion_txt


def xread(xfile, xcount=64, xlabel='', *, xencoding='utf8', xseek=0, xwhence=io.SEEK_SET):
    sep(xfile + ' ' + xlabel, 64)
    if xwhence not in {io.SEEK_SET, io.SEEK_END}:
        print('Only supported seeking from beginning or EOF.', file=sys.stderr)
        return
    if xwhence == io.SEEK_END:
        if xseek >= 0:
            print('Seek not to a negative value against EOF.', file=sys.stderr)
            return
        with open(xfile, 'rb') as ft:
            ft.seek(xseek, xwhence)
            xseek = ft.tell()
    f1 = open(xfile, encoding=xencoding)
    text = None

    def xtry_once():
        nonlocal text
        f1.seek(xseek)
        text = f1.read(xcount)

    while True:
        try:
            xtry_once()
            break
        except UnicodeDecodeError:
            xseek += 1
            print('', end='', flush=True)
            print(f'seek += 1 for {xfile} {xlabel}', file=sys.stderr)
    print(text)
    f1.close()


xread(linux_words_txt, xlabel='read')
xread(red_mansion_txt, 1024,
      xseek=0, xlabel='read 1024')

xsingle_chars = 573 + 65
xread(red_mansion_txt, 1024,
      xseek=(xsingle_chars + (1024 - xsingle_chars) * 5 // 2), xlabel='seek some, read 1024')

end_single_chars = 18784
xread(red_mansion_txt, 1024,
      xseek=-(1024 * 5 // 2 + end_single_chars), xwhence=io.SEEK_END, xlabel='seek from end, read 1024')
